package com.buxiaoxia.controller;


import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.*;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;


@RestController
public class LoginController {

    @RequestMapping("/load")
    public ModelAndView load() {
        return new ModelAndView("ftl/login");
    }

    /**
     * 模拟本应用通过用户名密码登录
     * @param request
     * @return
     * @throws IOException
     */
    @RequestMapping(value = {"/login"},method = RequestMethod.POST)
    public Map login(HttpServletRequest request, HttpServletResponse rep) throws Exception {
        String username=request.getParameter("username");
        String password=request.getParameter("password");
        String  location = "http://localhost:8081/oauth/token?username="+username+"&password="+password+
                "&grant_type=password&scope=foo&client_id=fooClientIdPassword&client_secret=secret";
        ResponseEntity<String>  response = new TestRestTemplate().exchange(location, HttpMethod.POST,new HttpEntity<>(new HttpHeaders()),
                String.class);
        Map map=new HashMap<>();
        rep.setStatus(response.getStatusCode().value());
         map = changeTokenMessage(response,map);

        return map;
    }

    public Map changeTokenMessage(ResponseEntity<String> response, Map map) throws Exception {
        //判断获取access token 是否成功
        if( !HttpStatus.OK.equals(response.getStatusCode())) {
            throw new Exception("token获取失败！");
        }
        //获取access_token信息
        HashMap<?, ?> jwtMap = new ObjectMapper().readValue(response.getBody(), HashMap.class);
        String accessToken = (String) jwtMap.get("access_token");
        map.put("access_token", jwtMap.get("access_token"));
        map.put("refresh_token", jwtMap.get("refresh_token"));
        map.put("expires_in", jwtMap.get("expires_in"));
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "bearer " + accessToken);
        response = new TestRestTemplate().exchange("http://127.0.0.1:8084/user", HttpMethod.GET,
                new HttpEntity<>(null, headers), String.class);
        jwtMap = new ObjectMapper().readValue(response.getBody(), HashMap.class);
        map.put("exp",jwtMap.get("exp"));
        map.put("username",jwtMap.get("username"));

        map.put("authorities",jwtMap.get("authorities"));

        return map;
    }

    /**
     * 刷新缓存
     * @param request
     * @return
     * @throws Exception
     */
    @RequestMapping(value = {"/refreshToken"},method = RequestMethod.POST)
    public Map refreshToken(HttpServletRequest request,HttpServletResponse rep) throws Exception {
        String refresh_token=request.getParameter("refresh_token");
        String  location = "http://localhost:8081/oauth/token?grant_type=refresh_token"+
                "&refresh_token="+refresh_token+
                "&client_id=fooClientIdPassword"+
                "&client_secret=secret";
        ResponseEntity<String>  response = new TestRestTemplate().exchange(location, HttpMethod.POST,new HttpEntity<>(new HttpHeaders()),
                String.class);
        rep.setStatus(response.getStatusCode().value());
        if( !HttpStatus.OK.equals(response.getStatusCode())) {
            throw new Exception("刷新缓存失败！");
        }
        HashMap<?, ?> jwtMap = new ObjectMapper().readValue(response.getBody(), HashMap.class);
        Map map=new HashMap<>();
        map.put("access_token", jwtMap.get("access_token"));
        map.put("refresh_token", jwtMap.get("refresh_token"));
        map.put("expires_in", jwtMap.get("expires_in"));
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "bearer " + jwtMap.get("access_token"));
        response = new TestRestTemplate().exchange("http://127.0.0.1:8084/user", HttpMethod.GET,
                new HttpEntity<>(null, headers), String.class);
        jwtMap = new ObjectMapper().readValue(response.getBody(), HashMap.class);
        map.put("exp",jwtMap.get("exp"));
        map.put("username",jwtMap.get("username"));
        map.put("authorities",jwtMap.get("authorities"));
        return map;
    }
    /**
     * 模拟第三方登录回调第三方的接口
     * @param request
     * @return
     * @throws Exception
     */
    @RequestMapping( value = {"/login/my"},method = RequestMethod.GET)
    public ModelAndView loginMy( HttpServletRequest request) throws Exception {
        String code =request.getParameter("code");
        String redirectUrls="http://127.0.0.1:8084/login/my";
        String  location = "http://127.0.0.1:8081/oauth/token?"
                + "grant_type=authorization_code&code="+code+"&client_id=barClientIdPassword&redirect_uri={redirectUrl}&client_secret=secret";
        ResponseEntity<String>  response = new TestRestTemplate().exchange(location, HttpMethod.POST,new HttpEntity<>(new HttpHeaders()),
                String.class, redirectUrls);
        //获取access_token信息
        ModelAndView model = changeToken(response);

       return  model;
    }
    public ModelAndView changeToken(ResponseEntity<String>  response) throws IOException {
        //判断获取access token 是否成功
        if( !HttpStatus.OK.equals(response.getStatusCode())) {
            return new ModelAndView("ftl/false");
        }
        //获取access_token信息
        HashMap<?, ?> jwtMap = new ObjectMapper().readValue(response.getBody(), HashMap.class);
        String accessToken = (String) jwtMap.get("access_token");
        String refreshToken = (String) jwtMap.get("refresh_token");

        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "bearer " + accessToken);
        response = new TestRestTemplate().exchange("http://127.0.0.1:8084/user", HttpMethod.GET,
                new HttpEntity<>(null, headers), String.class);
        jwtMap = new ObjectMapper().readValue(response.getBody(), HashMap.class);
        String userName = (String) jwtMap.get("username");
        ArrayList list=(ArrayList) jwtMap.get("authorities");
        StringBuffer authority=new StringBuffer();
        for (Object t : list) {
            Map obj = (Map) t;
            authority.append(","+obj.get("authority"));
        }
        ModelAndView model =new ModelAndView();
        model.addObject("userName",userName);
        model.addObject("authority",authority);
        model.setViewName("ftl/success");
        return model;
    }




    /**
     * 定义用户信息
     *
     * @param
     * @return
     */
    @PreAuthorize("hasRole('ROLE_USER')")
    @RequestMapping(value = "/user", method = RequestMethod.GET)
    public ResponseEntity getUser(OAuth2Authentication authentication ) {
        // 获取当前用户资源
        Map user = (Map) authentication.getPrincipal();
        ArrayList list=(ArrayList) user.get("authorities");
        String [] authority=null;
       if(list!=null && list.size()>0) {
           authority = new String[list.size()];
       }
         int i=0;
        for (Object t : list) {
            Map obj = (Map) t;
            authority[i]=obj.get("authority").toString();
            i++;
        }
        final String[] finalAuthority = authority;
        return new ResponseEntity<>(new HashMap<String, Object>() {{
            put("username", user.get("user_name"));
            put("name", user.get("name"));
            put("authorities", finalAuthority);
            put("exp", user.get("exp"));
        }}, HttpStatus.OK);
    }

}
